package com.stenio.fancat.service;

import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stenio.fancat.domain.ActOperLog;
import com.stenio.fancat.domain.ActStatistics;
import com.stenio.fancat.domain.ActType;
import com.stenio.fancat.domain.Activity;
import com.stenio.fancat.domain.Brand;
import com.stenio.fancat.domain.bo.ActivityBO;
import com.stenio.fancat.form.ActivityForm;
import com.stenio.fancat.mapper.ActOperLogMapper;
import com.stenio.fancat.mapper.ActStatisticsMapper;
import com.stenio.fancat.mapper.ActTypeMapper;
import com.stenio.fancat.mapper.ActivityMapper;
import com.stenio.fancat.storage.Storage;
import com.stenio.fancat.storage.StoragePage;
import com.stenio.fancat.util.StringUtil;

/**
 * 活动模块服务实现类
 */
@Service
public class ActivityService extends ServiceImpl<ActivityMapper, Activity> {

	@Autowired
	private ActivityMapper activityMapper;
	@Autowired
	private ActOperLogMapper actOperLogMapper;
	@Autowired
	private ActStatisticsMapper actStatisticsMapper;
	@Autowired
	private ActTypeMapper actTypeMapper;
	@Autowired
	private BrandService brandService;
	@Autowired
	private Storage storage;
	@Autowired
	private UserService userService;
	@Value("${redirectURLPrefix}")
	public String redirectURLPrefix;

	private static final Logger logger = LoggerFactory.getLogger(ActivityService.class);

	/**
	 * 最热、最新、通过BrandId查询活动
	 * 
	 * @param activityForm
	 *            活动实体
	 * @return
	 */
	public Page<ActivityBO> queryActivityInfosPage(ActivityForm activityForm) {
		Page<ActivityBO> page = new Page<>(activityForm.getCurrentPageNo(), activityForm.getPageSize());
		Activity act = new Activity();
		try {
			BeanUtils.copyProperties(act, activityForm);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("参数转换有误");
		}
		return page.setRecords(this.baseMapper.selectByConditionPage(page, act));
	}

	/**
	 * 获取活动类型
	 * 
	 * @return 活动类型列表
	 */
	public List<ActType> queryActivityType() {
		return actTypeMapper.selectList(null);
	}

	/**
	 * 新增活动
	 * 
	 * @param act
	 */
	@Transactional
	public void saveActivity(ActivityForm activityForm) {
		// 验证必填参数
		if (null == activityForm || StringUtils.isBlank(activityForm.getPublishTitle()) || StringUtils.isBlank(activityForm.getBrandName())
				|| StringUtils.isBlank(activityForm.getArticleAddress()) || null == activityForm.getUserId()
				|| null == activityForm.getTotleCandy() || null == activityForm.getTapCandy() || null == activityForm.getResendCandy()) {
			throw new RuntimeException("活动信息不完整");
		}
		
		Activity activity = new Activity();
		try {
			BeanUtils.copyProperties(activity, activityForm);
		} catch (Exception e1) {
			e1.printStackTrace();
			throw new RuntimeException("参数转换有误");
		}

		// 没有发布的品牌时需要新增品牌
		String brandName = activity.getBrandName();
		Integer brandId = activity.getBrandId();
		if (null == brandId) {
			List<Brand> brands = brandService.queryBrandByName(brandName);
			if (null != brands && brands.size() > 0) {
				activity.setBrandId(brands.get(0).getBrandId());
			} else {
				Brand entity = new Brand();
				entity.setBrandName(brandName);
				brandService.saveBrand(entity);
				activity.setBrandId(entity.getBrandId());
			}
		}
		// 设置活动默认值
		if (null == activity.getActTypeId()) {
			activity.setActTypeId(1);
			activity.setPublishType("转发");
		}
		activity.setReleaseState("1");
		activity.setTransformAddress("");
		try {
			StoragePage storagePage = storage.storage(activity.getArticleAddress());
			activity.setGrabAddress(storagePage.getHtmlUrl());
		} catch (Exception e) {
			// e.printStackTrace();
			activity.setGrabAddress("");
			logger.error("==>活动URL解析失败{}", e);
		}
		activityMapper.insertSelective(activity);

		// 设置并保存活动统计数据
		ActStatistics ActStt = new ActStatistics();
		ActStt.setActId(activity.getActId());
		ActStt.setResendCount(0l);
		ActStt.setSurplusCandy(activity.getTotleCandy());
		ActStt.setTapCount(0l);
		ActStt.setThumbs(0l);
		actStatisticsMapper.insertSelective(ActStt);

		activity.setTransformAddress(redirectURLPrefix + activity.getActId() + "/");
		activityMapper.updateByPrimaryKey(activity);
	}

	/**
	 * 当平台用户点击、转发活动时需要保存活动统计已经用户账户数据
	 * 
	 * @param actId
	 *            活动ID
	 * @param userId
	 *            操作用户ID
	 * @param type
	 *            0点击，1转发，2点赞
	 * @param ip
	 *            ip地址
	 */
	@Transactional
	public void saveActOperation(Integer actId, Integer userId, int type, String ip) {
		if (!StringUtil.isIP(ip)) {
			throw new RuntimeException("IP参数格式错误");
		}
		int amount = 0;
		// 获取活动信息，转发奖励、发布人ID
		Activity activity = activityMapper.selectById(actId);
		if (null == activity) {
			throw new RuntimeException("活动结束");
		}
		Integer publishId = activity.getUserId();
		if (type == 0)
			amount = activity.getTapCandy();
		if (type == 1)
			amount = activity.getResendCandy();

		// 增加转发人奖励数据，平台外部的用户点击活动时url中可能没有转发用户ID
		if (null != userId && userId > 0) {
			ActOperLog entity = new ActOperLog();
			entity.setUserId(userId);
			entity.setActId(actId);
			entity.setOperType(type);
			ActOperLog actOperLog = actOperLogMapper.selectOne(entity);
			// 同一活动多次转发、点击不计数
			if (null != actOperLog) {
				return;
			}
			userService.saveUserAccount(userId, amount, 0);
		}
		ActOperLog actOperLog = new ActOperLog();
		actOperLog.setActId(actId);
		actOperLog.setActTypeId(activity.getActTypeId());
		actOperLog.setBrandId(activity.getBrandId());
		actOperLog.setOperType(type);
		actOperLog.setReward(amount);
		actOperLog.setUserId(userId);
		actOperLog.setIpAddr(ip);
		// 减少发布人的账户数据
		userService.saveUserAccount(publishId, amount, 1);
		// 通过活动ID减统计数据
		saveActStatistics(actId, amount, type);
		actOperLogMapper.insertSelective(actOperLog);
	}

	/**
	 * 当非平台用户点击、转发活动时需要保存活动统计已经用户账户数据
	 * 
	 * @param url
	 *            活动URL格式后缀:"/index/send/actId/userId/"
	 */
	@Transactional
	public String saveActOperation(String actURL, String ip) {
		if (StringUtils.isBlank(actURL) || !StringUtil.isIP(ip)) {
			throw new RuntimeException("参数格式错误");
		}
		String[] array = actURL.split("/");
		// 获取活动id
		Integer actId = Integer.valueOf(array[3]);

		// 获取活动信息
		Activity activity = this.selectById(actId);
		if (null == activity || null == activity.getActId()) {
			throw new RuntimeException("活动数据异常");
		}
		// 获取活动操作日志
		Integer count = actOperLogMapper.selectCount(new EntityWrapper<ActOperLog>().eq(ActOperLog.ACT_ID, actId)
				.eq(ActOperLog.IPADDR, ip).eq(ActOperLog.OPER_TYPE, 0));
		// 同一个活动同一个ip点击仅记录1次
		if (count != 0) {
			// 获取获取活动统计信息
			ActStatistics actStatistics = new ActStatistics();
			actStatistics.setActId(actId);
			ActStatistics entity = actStatisticsMapper.selectOne(actStatistics);
			if (null == entity || null == entity.getId()) {
				throw new RuntimeException("活动统计数据异常");
			}

			entity.setTapCount(entity.getTapCount() + 1);
			actStatisticsMapper.updateById(entity);

			ActOperLog actOperLog = new ActOperLog();
			actOperLog.setActId(actId);
			actOperLog.setActTypeId(activity.getActTypeId());
			actOperLog.setBrandId(activity.getBrandId());
			actOperLog.setOperType(0);
			actOperLog.setIpAddr(ip);
			actOperLogMapper.insertAllColumn(actOperLog);
		}
		return activity.getArticleAddress();

	}

	/**
	 * 增加减少活动统计数据
	 * 
	 * @param actId
	 *            活动Id
	 * @param amount
	 *            操作金额
	 * @param type,0点击，1转发，2点赞
	 */
	@Transactional
	public void saveActStatistics(Integer actId, Integer amount, int type) {
		// 通过活动ID减统计数据
		ActStatistics entity = new ActStatistics();
		entity.setActId(actId);
		ActStatistics acts = actStatisticsMapper.selectOne(entity);
		if (null == acts || null == acts.getId()) {
			throw new RuntimeException("活动统计数据异常");
		}

		// 减少活动统计数据
		Integer surplusCandy = acts.getSurplusCandy();
		// 判断余额不足
		if (amount > surplusCandy) {
			throw new RuntimeException("活动余额不足,剩余金额为:" + surplusCandy);
		}
		acts.setSurplusCandy(acts.getSurplusCandy() - amount);
		// 增加活动统计数据
		if (type == 0)
			acts.setTapCount(acts.getTapCount() + 1);
		if (type == 1)
			acts.setResendCount(acts.getResendCount() + 1);
		if (type == 2)
			acts.setThumbs(acts.getThumbs() + 1);
		actStatisticsMapper.updateAllColumnById(acts);
	}

}
